<template>
  <div
    class="content-box"
    :class="{ padding: customLoading }"
    ref="mainListBox"
    @touchstart="touchEventStart"
    @touchmove="touchEventMove"
    @touchend="touchEventEnd"
    :style="{ top: currentTop + 'px' }"
  >
    <van-pull-refresh
      success-text="刷新成功"
      v-model="isLoading"
      @refresh="onRefresh"
      :disabled="!dropdownRefresh"
    >
      <van-list
        class="list-box"
        v-model="loading"
        :finished="finished"
        :error.sync="haveError"
        @load="onLoad"
        :style="{ 'background-color': bgColor }"
        :offset="offset"
      >
        <!-- flex瀑布流容器 -->
        <template v-if="falls">
          <div
            class="row-box"
            :style="{
              'padding-left': insideMargin + 'px',
              'padding-right': insideMargin + 'px',
              'padding-top': marginTop + 'px',
              'padding-bottom': marginTop + 'px'
            }"
          >
            <div class="falls-left">
              <template v-for="(item, index) in dataSource">
                <div
                  v-if="index % 2 === 1"
                  :key="index"
                  class="falls-left-item"
                  :style="{
                    'margin-bottom': lineSpacing + 'px',
                    width: itemWidth,
                    'background-color': bgColor
                  }"
                >
                  <slot name="left" v-bind:data="item"></slot>
                </div>
              </template>
            </div>
            <div class="falls-right">
              <template v-for="(item, index) in dataSource">
                <div
                  v-if="index % 2 === 0"
                  :key="index"
                  class="falls-right-item"
                  :style="{
                    'margin-bottom': lineSpacing + 'px',
                    width: itemWidth,
                    'background-color': bgColor
                  }"
                >
                  <slot name="right" v-bind:data="item"></slot>
                </div>
              </template>
            </div>
          </div>
        </template>
        <!-- felx瀑布流容器 -->

        <template #default v-if="!falls">
          <div class="row-box">
            <default-page v-if="!dataSource.length && !loading">
              <p class="defaultText" v-if="defaultPageText">
                {{ defaultPageText }}
              </p>
            </default-page>
            <!-- :class="index%3!==0?'cell-box:''"      'margin-right':
                  (index > 0 && index % 2) !== 0
                    ? columnSpacing + 3 + 'px'
                    : '0',-->
            <div
              v-for="(item, index) in dataSource"
              :key="index"
              v-else
              :class="[(index > 0 && index % 2) !== 0 ? 'cell-box' : '']"
              @click="parentClick(item)"
              :style="{
                'margin-bottom': lineSpacing + 'px',
                'background-color': bgColor
              }"
            >
              <slot v-bind:data="item"></slot>
            </div>
          </div>
        </template>
        <template #finished v-if="dataSource.length != 0 && !customLoading">
          <span v-if="hasMore"></span>
          <span v-else-if="haveError"></span>
          <span v-else class="finished-text">{{ finishedText }}</span>
        </template>
        <template #error>
          <span @click="onErrorRefresh">请求失败，点击重新加载</span>
        </template>

        <!-- loading slot -->
        <template #loading>
          <div class="load-box">
            <van-loading size="24px" class="loading" color="#f00"></van-loading>
          </div>
        </template>
        <!-- loading slot -->
      </van-list>
    </van-pull-refresh>
    <!-- 自定义上拉刷新 -->
    <div class="load-box" v-if="customLoading">
      <van-loading size="24px" class="loading" color="#f00">
        刷新中...
      </van-loading>
    </div>
  </div>
</template>

<script>
import defaultPage from "@/components/template/DefaultPage.vue";
export default {
  name: "listThree",
  props: {
    apiUrl: {
      //列表数据的请求接口API地址
      type: String,
      required: true
    },
    apiParams: {
      //列表数据的请求接口的参数对象，默认为current=1&size=10
      type: Object,
      default: () => {}
    },
    insideMargin: {
      //列表的内间距-左右的值相等
      type: Number,
      default: 10
    },
    marginTop: {
      //列表的外间距-上下的值相等
      type: Number,
      default: 10
    },
    lineSpacing: {
      //列表的行间距
      type: Number,
      default: 10
    },
    columnSpacing: {
      //列表的列间距
      type: Number,
      default: 10
    },
    dropdownRefresh: {
      //是否支持下拉刷新 默认不支持
      type: Boolean,
      default: false
    },
    bgColor: {
      type: String,
      default: "#fff"
    },
    falls: {
      // 两列瀑布流布局,插槽名：left，right
      type: Boolean,
      default: false
    },
    offset: {
      type: String,
      default: "100"
    },
    finishedText: {
      type: String,
      default: "更多精彩，敬请期待"
    },
    //缺省页的详情
    defaultPageText: {
      type: String
    }
  },
  watch: {
    columnSpacing: {
      handler: function (newVal) {
        this.curColumnSpaing = newVal;
      },
      immediate: true
    },
    apiParams(params) {
      this.onLoad(params);
    }
  },
  data() {
    return {
      dataSource: [], //列表的数据源
      screenWidth: 0, //保存屏幕宽度
      curColumnSpaing: 0, //保存当前的块的间隔宽度
      // 分页
      pagination: {
        current: 1,
        pageSize: 10,
        total: 0
      },
      loading: false,
      finished: false,
      haveError: false,
      isLoading: false, //加载完成 上拉是否加载完成
      hasMore: false,
      currentTop: 0,
      customLoading: false
    };
  },
  components: { defaultPage },
  computed: {
    itemWidth() {
      //计算每一列的宽度
      let result = `calc(33.3% - ${this.columnSpacing - 0.1}px)`;
      return result;
    }
  },
  mounted() {
    this.$nextTick(() => {
      const that = this;
      window.onresize = () => {
        return (() => {
          window.screenWidth = document.body.clientWidth;
          that.screenWidth = window.screenWidth;
        })();
      };
    });
  },
  methods: {
    //自定义方法
    parentClick(item) {
      this.$emit("itemClick", item);
    },
    //上拉刷新方法
    onRefresh() {
      this.pagination.current = 1;
      this.dataSource = [];
      this.onLoad();
    },
    //这里是list 的请求事件
    onLoad(p = null) {
      if (!this.apiUrl) {
        // eslint-disable-next-line
        // console.err("三列列表的请求地址不能为空！！！");
        this.loading = false;
        this.finished = true;
        return;
      }
      let params = {};
      if (!this.apiParams && !p) {
        params.current = this.pagination.current;
        params.size = this.pagination.pageSize;
      } else if (p) {
        params = Object.assign({ current: 1, size: 10 }, p);
        // 重置列表数据
        this.dataSource = [];
        // 重置分页器状态
        this.pagination.current;
      } else {
        params.current = this.pagination.current;
        params.size = this.pagination.pageSize;
        params = Object.assign(params, this.apiParams);
      }
      let that = this;
      this.$axios
        .get(this.apiUrl, { params: params })
        .then(res => {
          if (this.isLoading) {
            this.dataSource = [];
            this.isLoading = false;
          }
          this.isLoading = false; //上拉刷新成功
          if (res.code === 200) {
            //这里取值的规范暂时按照综合管理平台的结构进行取值。后续按需修改。
            let resData = res.data.records || res.data || [];
            this.dataSource = this.dataSource.concat(resData);
            this.pagination.total = Number(res.data.total) || resData.length;
            if (resData.length < params.size) {
              this.finished = true;
            } else {
              this.pagination.current++;
            }
          } else {
            this.$toast.fail("查询失败！");
          }
        })
        .catch(function (error) {
          // eslint-disable-next-line
          // console.log(error);
          this.finished = true;
          that.haveError = true;
        })
        .finally(() => {
          // always executed
          this.loading = false;
          // this.finished = true;
          // this.isLoading = false;
        });
    },
    //错误文本的点击事件
    onErrorRefresh() {
      this.haveError = false;
      this.finished = false;
      this.loading = true;
      this.onLoad();
    },
    resetPagination() {
      this.pagination = {
        current: 1,
        pageSize: 10,
        total: 0
      };
    },
    touchEventStart(e) {
      if (!this.finished) return; // 列表未加载完毕不触发效果
      this.start = e.changedTouches[0].clientY;
    },
    touchEventMove(e) {
      if (!this.finished) return; // 列表未加载完毕不触发效果
      const current = (this.start - e.changedTouches[0].clientY) / 2;
      if (current < 50) {
        this.currentTop = -current;
      }
    },
    touchEventEnd(e) {
      this.currentTop = 0;
      if (!this.finished) return; // 列表未加载完毕不触发效果
      const current = this.start - e.changedTouches[0].clientY;
      if (current < 0) return; // 起始值大于结束值刷新，反之return
      this.customLoading = true;
      setTimeout(() => {
        this.customLoading = false;
      }, 2000);
    }
  }
};
</script>

<style scoped lang="scss">
.defaultText {
  text-align: center;
  font-size: 24px;

  font-weight: 500;
  color: rgba(193, 199, 215, 1);
}
.load-box {
  display: flex;
  justify-content: center;
}
.content-box {
  width: 100%;
  height: 100%;
  position: relative;
  &.padding {
    transition: top ease-in-out 0.3s;
  }
  .list-box {
    background: #fff;
    // overflow: hidden;
    .row-box {
      display: flex;
      padding: 20px;
      // justify-content: space-between;
      flex-direction: row;
      flex-wrap: wrap;
      .left-box {
        background: #fff;
        overflow: hidden;
        box-sizing: border-box;
      }
      .right-box {
        background: #fff;
        overflow: hidden;
        box-sizing: border-box;
      }
      .cell-box {
        margin-right: 20px;
      }
      .falls-left,
      .falls-right {
        flex-direction: column;
        width: 33.3%;
      }
    }
  }
  .finished-text {
    font-size: 24px;
    line-height: 36px;
    font-weight: 500;
    color: #cccccc;
  }
}
</style>
